#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <Adafruit_AHTX0.h>
#include <Adafruit_SSD1306.h>
#include <ArduinoJson.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <WiFiClient.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
#include <time.h>
#include <ir_Gree.h>
#include <EEPROM.h>
#include <Wire.h>
//#include <IPAddress.h>
#include <ESP8266HTTPClient.h>

//版本号
String ver = "V3.4";

// 引脚定义
#define BUTTON_PIN 0       // GPIO0

// 参数定义
#define EEPROM_ADDR 0            //起始eeprom存储地址
#define DEBOUNCE_TIME 50          // 消抖
#define MULTI_CLICK_INTERVAL 600  // 五次点击的时间窗口(毫秒)
#define REQUIRED_CLICKS 5         // 需要5次点击

//软件IIC--SDA和SCL引脚定义
#define SDAPIN 0
#define SCLPIN 2

// OLED配置
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// AHT10传感器
Adafruit_AHTX0 aht;

// 红外发射
const uint16_t kIrLed = 3;  // ESP01S的GPIO3
IRGreeAC irsend(kIrLed);

// 巴法云配置
WiFiClient bfClient;

// MySQL配置
WiFiClient mysqlClient;
MySQL_Connection conn(&mysqlClient);
IPAddress mysqlIp;

// 获取外网IP的服务地址
const char* ip_service1 = "http://ipinfo.io/ip";
const char* ip_service2 = "http://api.ipify.org";
const char* ip_service3 = "http://icanhazip.com";

// 全局变量
unsigned long lastSensorRead = 0;
unsigned long lastBfSend = 0;
unsigned long lastDisplayOff = 0;
unsigned long lastDailyReport = 0;
bool displayState = true;
bool pressDisplayState = false;
float temperature = 0;
float humidity = 0;
int inserted = 0;
String externalIP = "";

// 心跳定时器
unsigned long lastHeartbeat = 0;
const unsigned long heartbeatInterval = 30000; // 30秒心跳
unsigned long lastReportTime = 0;

// 按钮状态变量
unsigned long lastButtonPress = 0;
bool buttonPressed = false;
int clickCount = 0;

// 空调状态结构体
struct AirConditioner {
  int power = 0; // 0:off, 1:on
  int mode = 1;  // 0-5
  int temp = 26; // 16-30
  int fan = 2;   // 0-3
} acState;

// 存储配置的结构体
struct Config {
  char tcp_server[64];  // TCP服务器地址
  int tcp_port;         // TCP服务器端口
  char uid[64];         // 巴法云UID
  char airTopic[32];       // 空调订阅主题
  char tempTopic[32];       // 温湿度发布主题  
  char apiKey[64];
  int type;        // 消息类型
  char ac_brand[32];    // 空调品牌
  char mysqlServer[32];  //mysql服务器地址
  char mysqlUser[32];    //mysql用户名
  char mysqlPassword[64];  //mysql密码
  char mysqlDB[32];     //mysql数据库名
  int report_interval;  // 上报间隔(秒)

};
Config config;

// 默认配置 
Config defaultConfig = {
 "bemfa.com",  // tcp_server (巴法云TCP服务器)
  8344,         // tcp_port (巴法云TCP端口)
  "",           // uid
  "aircd005", // airTopic
  "temp004",   // tempTopic
  "",        //apiKey
  3,         // type消息类型
  "gree",        // ac_brand (默认格力)
  "",      //mysql服务器地址
  "",      //mysql用户名
  "",      //mysql密码
  "",      //mysql数据库名
  30            // report_interval (60秒)
};

// 函数声明
void readSensorData();
void updateDisplay();
void connectToBfCloud();
void processBfMessage(String message);
void controlAC(int power, int mode, int fan, int temp);
void sendToBfCloud();
void connectToMySQL();
void sendToMySQL();
void configModeCallback(WiFiManager *myWiFiManager);
void sendGreeAC(int power, int mode, int fan, int temp);
void sendAuxAC(int power, int mode, int fan, int temp);
void printState();
void loadConfig();
void saveConfig();
void checkButton();
bool strToIp(String ipStr , IPAddress &resultIP);
void getExternalIP();
void sendIPToBaFa();
String getIPFromService(const char* serviceUrl);

void setup() {
  Serial.begin(115200);
  EEPROM.begin(sizeof(Config));

    // 初始化引脚
  pinMode(BUTTON_PIN, INPUT_PULLUP);
   
  // 初始化红外
  pinMode(kIrLed,OUTPUT);
  digitalWrite(kIrLed,LOW);
  irsend.begin();
  delay(200);

  //初始化软件IIC
  Wire.begin(SDAPIN,SCLPIN);

  // 初始化OLED
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 显示屏参数错误！"));
    //for(;;); // 卡死
  }
  

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("-Version-");
  display.setCursor(32,16);
  display.println(ver);
  display.display();
  delay(3000);

  // 初始化AHT10
  if (!aht.begin()) {
    Serial.println("无法找到AHT传感器!");
    display.println("AHT10 err!");
    display.display();
    delay(5000);
  }

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Starting..");
  display.display();
  delay(2000);
  loadConfig();

  // Serial.println("config.apiKey:" + String(config.apiKey));  //
  // Serial.println("config.airTopic:" + String(config.airTopic));  //
  // Serial.println("config.tcp_server:" + String(config.tcp_server));  //

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(36,0);
  display.println("WiFi");
  display.setCursor(0,16);
  display.println("Conecting.");
  display.display();
  delay(1000);

  // WiFiManager配置
  WiFiManager wifiManager;
  
  // 设置配置AP回调
  wifiManager.setAPCallback(configModeCallback);

  // 设置自定义参数
  WiFiManagerParameter custom_bf_server("server", "巴法云服务器", config.tcp_server, 40);
  WiFiManagerParameter custom_bf_port("port", "巴法云端口", "8344", 6);
  WiFiManagerParameter custom_uid("uid", "巴法云UID", config.uid, 40);
  WiFiManagerParameter custom_temp_topic("tempTopic", "温度主题", config.tempTopic, 20);
  WiFiManagerParameter custom_aircd_topic("aircdTopic", "空调主题", config.airTopic, 20);
  WiFiManagerParameter custom_apikey("apikey", "API Key", "", 40);
  WiFiManagerParameter custom_type("type", "消息类型", "3", 3);
  WiFiManagerParameter custom_air_brand("airBrand", "空调品牌", config.ac_brand, 20);
  WiFiManagerParameter custom_mysql_server("mysqlServer", "MySQL服务器", config.mysqlServer, 40);
  WiFiManagerParameter custom_mysql_user("mysqlUser", "MySQL用户", "", 20);
  WiFiManagerParameter custom_mysql_password("mysqlPassword", "MySQL密码", "", 64);
  WiFiManagerParameter custom_mysql_db("mysqlDB", "MySQL数据库", config.mysqlDB, 20);
  WiFiManagerParameter custom_report_interval("report_interval", "上报间隔（秒）", "30", 4);
 
  wifiManager.addParameter(&custom_bf_server);
  wifiManager.addParameter(&custom_bf_port);
  wifiManager.addParameter(&custom_uid);
  wifiManager.addParameter(&custom_temp_topic);
  wifiManager.addParameter(&custom_aircd_topic);
  wifiManager.addParameter(&custom_apikey);
  wifiManager.addParameter(&custom_type);
  wifiManager.addParameter(&custom_air_brand);
  wifiManager.addParameter(&custom_mysql_server);
  wifiManager.addParameter(&custom_mysql_user);
  wifiManager.addParameter(&custom_mysql_password);
  wifiManager.addParameter(&custom_mysql_db);
  wifiManager.addParameter(&custom_report_interval);

  // 尝试连接保存的WiFi或启动配置AP
  if (!wifiManager.autoConnect("ESP01S_Config","1234567890")) {
    Serial.println("Failed to connect and hit timeout");
    delay(3000);
    ESP.reset();
    delay(5000);
  }

if (String(config.apiKey).length() < 10){
  Serial.println("apikey为空，保存数据到EEPROM！");
  strcpy(config.tcp_server , custom_bf_server.getValue());
  config.tcp_port = atoi(custom_bf_port.getValue());
  strcpy(config.uid , custom_uid.getValue());
  strcpy(config.tempTopic , custom_temp_topic.getValue());
  strcpy(config.airTopic , custom_aircd_topic.getValue());
  strcpy(config.apiKey , custom_apikey.getValue());
  config.type = atoi(custom_type.getValue());
  strcpy(config.ac_brand , custom_air_brand.getValue());
  strcpy(config.mysqlServer , custom_mysql_server.getValue());
  strcpy(config.mysqlUser , custom_mysql_user.getValue());
  strcpy(config.mysqlPassword , custom_mysql_password.getValue());
  strcpy(config.mysqlDB , custom_mysql_db.getValue());
  config.report_interval = atoi(custom_report_interval.getValue());
  saveConfig();
  }


  // 显示连接信息
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0,0);
  display.println("WiFi Connected!");
  display.print("IP: ");
  display.println(WiFi.localIP());
  display.display();
  // Serial.println("config.apiKey:" + String(config.apiKey));  //
  // Serial.println("config.airTopic:" + String(config.airTopic));  //
  // Serial.println("config.tcp_server:" + String(config.tcp_server));  //

  delay(5000);

  // 配置时间
  configTime(8 * 3600, 0, "pool.ntp.org", "time.nist.gov");
  
  // 连接巴法云
  connectToBfCloud();
  
  // 首次获取IP、发送到巴法云
  getExternalIP();
  if (externalIP != "") {
    Serial.println("首次获取IP、发送到巴法云");
    sendIPToBaFa();
  }

  // 连接MySQL (如果配置了)
  if(String(config.mysqlServer) != "") {
    Serial.println("数据库已配置，准备连接");

    bool convertOk = strToIp(String(config.mysqlServer),mysqlIp);
    if (!convertOk){
      Serial.println("IP地址格式错误");
      display.clearDisplay();
      display.setTextSize(2);
      display.setCursor(0,0);
      display.println("IP ADDRESS");
      display.setCursor(0,16);
      display.print("ERROR!!!");
      display.display();
      delay(3000);
      ESP.restart();
    }
    connectToMySQL();
  }
  //提示信息，正式版删除
  // Serial.print("bfserver:");Serial.println(config.tcp_server);
  // Serial.print("bfPort:");Serial.println(config.tcp_port);
  // Serial.print("uid:");Serial.println(config.uid);
  // Serial.print("tempTopic:");Serial.println(config.tempTopic);
  // Serial.print("aircdTopic:");Serial.println(config.airTopic);
  // Serial.print("apiKey:");Serial.println(config.apiKey);
  // Serial.print("airBrand:");Serial.println(config.ac_brand);
  // Serial.print("mysqlServer:");Serial.println(config.mysqlServer);
  // Serial.print("mysqlUser:");Serial.println(config.mysqlUser);
  // Serial.print("mysqlPassword:");Serial.println(config.mysqlPassword);
  // Serial.print("mysqlDB:");Serial.println(config.mysqlDB);
  // delay(2000);
  // //提示信息，正式版删除
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0,0);
  display.println("--START--");
  display.setCursor(0,16);
  display.print("SUCCESSED");
  display.display();
  delay(5000);
}

void loop() {
  //处理按键信息
  checkButton();

  // 处理巴法云消息
  if (!bfClient.connected()) {
    connectToBfCloud();
  } else {
    while (bfClient.available()) {
      String line = bfClient.readStringUntil('\n');
      line.trim();
      //提取关键数据
      int msgIndex = line.indexOf("msg=");

      if (msgIndex != -1){
        // 截取"msg="后面的所有内容
        String msgData = line.substring(msgIndex + 4); // 4是"msg="的长度
        // 输出结果
        Serial.println("提取到的msg数据:");
        Serial.println(msgData);
        // 解析消息 (格式: key1=value1&key2=value2...)
        processBfMessage(msgData);
      }else{
        Serial.println("接收的数据未找到msg字段,非遥控数据");
      }
    }

    // 读取传感器数据
    if (millis() - lastSensorRead >= 3000) {
      readSensorData();
      lastSensorRead = millis();
    }

    // // 显示管理
    // if (displayState && millis() - lastDisplayOff >= 3000) {
    //   display.clearDisplay();
    //   display.display();
    //   displayState = false;
    // } else if (!displayState && millis() - lastDisplayOff >= 5000) {
    // displayState = true;
    // updateDisplay();
    // lastDisplayOff = millis();
    // }

    // 发送数据到巴法云
    //Serial.print("millis= ");Serial.println(millis());
    //Serial.print("lastBfSend= ");Serial.println(lastBfSend);
    if (millis() - lastBfSend >= 30000) {
      Serial.println("满30秒发送数据到巴法云");
      sendToBfCloud();
      displayState = true;
      display.clearDisplay();
      display.setTextSize(2);
      display.setCursor(0,0);
      display.println("send data");
      display.setCursor(0,16);
      display.print("to bafa^_^");
      display.display();
      lastDisplayOff = millis();
      lastBfSend = millis();
    }
    if (displayState && millis() - lastDisplayOff >= 5000) {
      display.clearDisplay();
      display.display();
      displayState = false;
    }

    // 每日报告到MySQL
	
    if (millis() - lastDailyReport >= 600000) { // 每10分钟检查一次
      //发送IP地址到巴法云
      String previousIP = externalIP;
      getExternalIP();
      if (externalIP != "" && externalIP != previousIP) {
        sendIPToBaFa();
      }

      //以下为mysql
      time_t now = time(nullptr);
      if (now > 0) { // 确保时间已同步
        struct tm* timeinfo = localtime(&now);
        if (String(config.mysqlServer) != "") {
          // if ((timeinfo->tm_hour == 10 || timeinfo->tm_hour == 14) && 
          //   timeinfo->tm_min == 0 ) {
          Serial.print("tm_hour = ");
          Serial.println(timeinfo->tm_hour);

		      if ((timeinfo->tm_hour == 0 || timeinfo->tm_hour == 12)) inserted = 0;
          Serial.print("!inserted = ");
          Serial.println(!inserted);

          if ((timeinfo->tm_hour == 10 || timeinfo->tm_hour == 14)) {
              // 首次获取IP、发送到巴法云
              getExternalIP();
              if (externalIP != "") {
                Serial.println("获取IP、发送到巴法云");
                sendIPToBaFa();
              }       //每天发送两次ip

			      if (!inserted){
				      sendToMySQL();
			      }
          }else {
            Serial.println("时间未到不上传数据到mysql");
          }
        }else {
          Serial.println("数据库信息未配置");
        }
      }

      display.clearDisplay();
      display.setTextSize(2);
      display.setCursor(0,0);
      display.println("!inserted");
      display.setCursor(0,16);
      display.print(!inserted);
      display.display();  


      lastDailyReport = millis();
    }
  }
}

// ========== 配置管理 ==========
void loadConfig() {
  Serial.println("==============开始loadconfig============");
  EEPROM.get(EEPROM_ADDR, config);
  Serial.println("读取config配置");
//  Serial.println("apikey："+ String(config.apiKey));
  // 检查是否第一次使用
  if (String(config.apiKey).length() < 10) {
    // 使用默认配置
    Serial.println("第一次使用，设置参数为默认值");
    
    memcpy(&config, &defaultConfig, sizeof(Config));
    // 保存配置参数
    saveConfig();
  }
   Serial.println("==============结束loadconfig============");
}

void saveConfig() {
  EEPROM.put(EEPROM_ADDR, config);
  EEPROM.commit();
}

void resetConfig() {
  // 1. 清除保存的WiFi配置
  WiFiManager wifiManager;
  wifiManager.resetSettings();
  Serial.println("WiFi 已重置");
  // 2. 重置EEPROM中的自定义参数  
  memcpy(&config, &defaultConfig, sizeof(Config));
  saveConfig();
  Serial.println("EEPROM 已重置");
  // 3. 确保GPIO0释放
  pinMode(BUTTON_PIN, INPUT_PULLUP);

    // 5. 延迟确保设置生效
  delay(1000);
    // 6. 重启设备（将进入配置模式）
  Serial.println("重启进入配置模式"); 
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0,0);
  display.println("reset");
  display.setCursor(0,16);
  display.print("restart");
  display.display();
  delay(5000);
  ESP.restart();
}

void readSensorData() {
  sensors_event_t humidity_event, temp_event;
  aht.getEvent(&humidity_event, &temp_event);
  
  temperature = temp_event.temperature;
  humidity = humidity_event.relative_humidity;
  
  if (displayState) {
    updateDisplay();
  }
}

void updateDisplay() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("T:");
  display.print(temperature, 1);
  display.print(" C ");
  display.print("H:");
  display.print(humidity, 1);
  display.println(" %");
  
  // 显示空调状态
  display.setCursor(0,16);
  display.print("AC: ");
  display.print(acState.power ? "ON " : "OFF ");
  display.print("M:");
  display.print(acState.mode);
  display.print(" T:");
  display.print(acState.temp);
  display.print(" F:");
  display.print(acState.fan);
  
  display.display();
}

void connectToBfCloud() {
  if (bfClient.connect(config.tcp_server, config.tcp_port)) {
    Serial.println("Connected to BfCloud");
    
    // 订阅主题
    String subTemp = "cmd=1&uid=" + String(config.apiKey) + "&topic=" + String(config.tempTopic) + "\r\n";
    String subAir = "cmd=1&uid=" + String(config.apiKey) + "&topic=" + String(config.airTopic) + "\r\n";
    
    bfClient.print(subTemp);
    bfClient.print(subAir);
    Serial.println("已订阅主题");
    display.clearDisplay();
    display.setTextSize(2);
    display.setCursor(0,0);
    display.print("BaFa conn");
    display.setCursor(0,16);
    display.print("successed");
    display.display();
    delay(2000);
  } else {
    Serial.println("BfCloud connection failed");
    display.clearDisplay();
    display.setTextSize(2);
    display.setCursor(0,0);
    display.print("BaFa conn");
    display.setCursor(0,16);
    display.print("failed");
    display.display();
    delay(2000);
  }
}

void processBfMessage(String message) {
  // 消息格式: {"power":"1","mode":"1","temp":"20","fan":"2","time":1756128904430}
  //Serial.println(message);
  
  // 解析JSON
  DynamicJsonDocument doc(256);
  DeserializationError error = deserializeJson(doc, message);
    
  if (error) {
    Serial.print("JSON parse failed: ");
    Serial.println(error.c_str());
    return;
  }
  
  // 检查消息是否包含空调控制参数
  if (doc.containsKey("power") || doc.containsKey("mode") || 
                      doc.containsKey("fan") || doc.containsKey("temp")) {
    acState.power = doc["power"] ;
    acState.mode = doc["mode"] ;
    acState.temp = doc["temp"] ;
    acState.fan = doc["fan"] ;
    
    // 发送红外信号
    // 控制空调
    controlAC(acState.power, acState.mode, acState.fan, acState.temp);
    
    // 更新显示
    if (displayState) {
      updateDisplay();
    }
  }else{
    Serial.println("数据不包含遥控信息");
  }

}

// ========== 空调控制 ==========
void controlAC(int power, int mode, int fan, int temp) {
  Serial.printf("Controlling AC: power=%d, mode=%d, fan=%d, temp=%d\n", 
               power, mode, fan, temp);
  Serial.print("准备发送遥控数据，当前空调品牌：");
  Serial.println(config.ac_brand);
  // 根据空调品牌发送不同的红外信号
  if (String(config.ac_brand) == "GREE" || String(config.ac_brand) == "gree") {
    sendGreeAC(power, mode, fan, temp);
    Serial.println("收到格力空调遥控数据");
  } 
  else if (String(config.ac_brand) == "MIDEA" || String(config.ac_brand) == "midea") {
    //sendMideaAC(power, mode, fan, temp);
    Serial.println("收到美的空调遥控数据");
  }
  else if (String(config.ac_brand) ==  "HAIER" || String(config.ac_brand) == "haier") {
    //sendHaierAC(power, mode, fan, temp);
    Serial.println("收到海尔空调遥控数据");
  }
  else if (String(config.ac_brand) ==  "AUX" || String(config.ac_brand) == "aux") {
    sendAuxAC(power, mode, fan, temp);
    Serial.println("收到奥克斯空调遥控数据");
  }
}

// 格力空调红外编码
void sendGreeAC(int power, int mode, int fan, int temp) {
    Serial.print("power =");
    Serial.println(power);
  // 电源状态 (0:关, 1:开)
  if (power == 1){
    irsend.on();
    
  }else{
    irsend.off();

  }
  
  // 模式 (0:自动, 1:制冷, 2:除湿, 3:送风, 4:制热)
  switch(mode) {
    case 0: irsend.setMode(kGreeAuto); break; // 自动
    case 1: irsend.setMode(kGreeCool); break; // 制冷
    case 2: irsend.setMode(kGreeDry); break; // 除湿
    case 3: irsend.setMode(kGreeFan); break; // 送风
    case 4: irsend.setMode(kGreeHeat); break; // 制热
    default: irsend.setMode(kGreeAuto); // 默认制冷
  }
  
  // 温度 (16-30℃)
  if (temp >= 16 && temp <= 30) {
    irsend.setTemp(temp);
  } else {
    irsend.setTemp(26); // 默认26℃
  }
  
  // 风速 (0:自动, 1:低, 2:中, 3:高)
  if (fan>=0 && fan <=3) {
    irsend.setFan(fan);
  }else{
    irsend.setFan(0);
  }
  
  // 发送红外信号 (使用NEC协议模拟)
  Serial.println("Sending IR command to A/C ...");
  irsend.send();
  printState();
  delay(50);
}

void sendAuxAC(int power, int mode, int fan, int temp) {

}

//串口输出红外控制信息
void printState() {
  // Display the settings.
  Serial.println("GREE A/C remote is in the following state:");
  Serial.printf("  %s\n", irsend.toString().c_str());
  // Display the encoded IR sequence.
  unsigned char* ir_code = irsend.getRaw();
  Serial.print("IR Code: 0x");
  for (uint8_t i = 0; i < kGreeStateLength; i++)
    Serial.printf("%02X", ir_code[i]);
  Serial.println();
}


void sendToBfCloud() {
  if (bfClient.connected()) {
    // 获取当前时间
    time_t now = time(nullptr);
    struct tm* timeinfo = localtime(&now);
    char timeStr[20];
    strftime(timeStr, sizeof(timeStr), "%H:%M:%S", timeinfo);
    
    // 构建消息
    String message = "msg=";
    message += "#" + String(temperature, 1);
    message += "#" + String(humidity, 1);
    message += "#" + String(timeStr);
    
    // 发送消息
    String pubCmd = "cmd=2&uid=" + String(config.apiKey) + "&topic=" + String(config.tempTopic) + "&" + message + "\r\n";
    //Serial.print("pubCmd= ");Serial.println(pubCmd);
    bfClient.print(pubCmd);
  }
}

bool strToIp(String ipStr , IPAddress &resultIP){
  char ipChar[ipStr.length() + 1];
  ipStr.toCharArray(ipChar , sizeof(ipChar));

  int ipSegments[4] = {0};
  int segmentIndex = 0;

  char *segment = strtok(ipChar , ".");
  while(segment != NULL && segmentIndex <4){
    ipSegments[segmentIndex] = atoi(segment);
    if (ipSegments[segmentIndex] < 0 || ipSegments[segmentIndex] > 255){
      return false;
    }
    segmentIndex++;
    segment = strtok(NULL , ".");
  }
  if (segmentIndex != 4){
    return false;
  }
  resultIP = IPAddress(ipSegments[0],ipSegments[1],ipSegments[2],ipSegments[3]);
  Serial.print("resultip:");
  Serial.println(resultIP);
  return true;
}

void connectToMySQL() {
  Serial.println("进入链接mysql状态");
  //Serial.println(config.mysqlUser);
  //Serial.println(mysqlIp);
  //if (WiFi.hostByName(config.mysqlServer, mysqlIp)) {         域名转换为IP地址
    if (conn.connect(mysqlIp, 3306, config.mysqlUser, config.mysqlPassword,config.mysqlDB)) {
      Serial.println("MySQL connected");
      display.clearDisplay();
      display.setTextSize(2);
      display.setCursor(0,0);
      display.print("MySQL conn");
      display.setCursor(0,16);
      display.print("successed");
      display.display();
      delay(2000);
    } else {
      Serial.println("MySQL connection failed");
      display.clearDisplay();
      display.setTextSize(2);
      display.setCursor(0,0);
      display.print("MySQL conn");
      display.setCursor(0,16);
      display.print("failed");
      display.display();
      delay(2000);
    }
  //}
}

void sendToMySQL() {
  if (!conn.connected()) {
    connectToMySQL();
  }
  
  if (conn.connected()) {
    // 获取当前时间
    time_t now = time(nullptr);
    struct tm* timeinfo = localtime(&now);
    char dateStr[11];
    char timeStr[9];
    String noon = "";
    if (timeinfo->tm_hour == 10) noon = "AM";
    if (timeinfo->tm_hour == 14) noon = "PM";
    strftime(dateStr, sizeof(dateStr), "%Y-%m-%d", timeinfo);
    strftime(timeStr, sizeof(timeStr), "%H:%M:%S", timeinfo);
    
    // 构建SQL语句
    char query[128];
    snprintf(query, sizeof(query), 
             "INSERT INTO temp_humi (date, time, temp, humi, info) VALUES ('%s', '%s', %.1f, %.1f,'%s')",
             dateStr, noon.c_str(), temperature, humidity, timeStr);
    
    // 执行查询
    MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
    int result = cur_mem->execute(query);

    
      display.setCursor(64,16);
      display.print(result);
      display.display(); 

	  if (result) inserted = 1;

    delete cur_mem;
  }
}

void configModeCallback(WiFiManager *myWiFiManager) {
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0,0);
  display.println("Config Mode");
  display.print("AP: ");
  display.println(myWiFiManager->getConfigPortalSSID());
  display.print("IP: ");
  display.println(WiFi.softAPIP());
  display.print("pass: ");
  display.println("1234567890");
  display.display();
}

void checkButton() {
  int buttonState = digitalRead(BUTTON_PIN);
  
  // 按钮按下(低电平)
  if (buttonState == LOW && !buttonPressed) {
    buttonPressed = true;
    pressDisplayState = true;
    lastDisplayOff = millis();
    delay(DEBOUNCE_TIME); // 消抖
    
    unsigned long currentTime = millis();
    
    // 检查是否在时间窗口内
    if (currentTime - lastButtonPress < MULTI_CLICK_INTERVAL) {
      clickCount++;
      Serial.print("按键次数: ");
      Serial.println(clickCount);
      
      // 视觉反馈 - 每次点击LED闪烁
      
      
      if (clickCount >= REQUIRED_CLICKS) {
        Serial.println("检测到五次按键! 开始重置所有配置...");
        // 确认反馈 - 快速闪烁3次
        
        resetConfig();
        clickCount = 0;

      }
    } else {
      // 新的一系列点击开始
      clickCount = 1;
      Serial.println("检测到首次按键");
   
    }
    
    lastButtonPress = currentTime;
  }

  //按键后执行显示
  if (pressDisplayState) {
    readSensorData();
    display.clearDisplay();
    display.setTextSize(2);
    display.setCursor(0,0);
    display.print("T:");
    display.print(temperature, 1);
    display.println(" C ");
    display.setCursor(0,16);
    display.print("H:");
    display.print(humidity, 1);
    display.println(" %");
    display.display();
    
  }
  //按键后屏幕显示5秒，关闭显示
  if (pressDisplayState && millis() - lastDisplayOff >= 5000) {
    display.clearDisplay();
    display.display();
    pressDisplayState = false;
  }
  
  // 按钮释放
  if (buttonState == HIGH && buttonPressed) {
    buttonPressed = false;
    delay(DEBOUNCE_TIME); // 消抖
  }
  
  // 重置点击计数(如果超过时间窗口)
  if (millis() - lastButtonPress > MULTI_CLICK_INTERVAL && clickCount > 0) {
    Serial.println("按键超时，重新计数");
    clickCount = 0;
    
  }
}

// 获取外网IP地址
void getExternalIP() {
  Serial.println("正在获取外网IP地址...");
  
  String newIP = getIPFromService(ip_service1);
  if (newIP == "") {
    newIP = getIPFromService(ip_service2);
  }
  if (newIP == "") {
    newIP = getIPFromService(ip_service3);
  }
  
  if (newIP != "") {
    externalIP = newIP;
    Serial.print("外网IP地址: ");
    Serial.println(externalIP);
  } else {
    Serial.println("获取外网IP失败!");
  }
}

// 从指定服务获取IP
String getIPFromService(const char* serviceUrl) {
  WiFiClient client;
  HTTPClient http;
  String ip = "";
  
  Serial.print("尝试从 ");
  Serial.print(serviceUrl);
  Serial.println(" 获取IP");
  
  if (http.begin(client, serviceUrl)) {
    int httpCode = http.GET();
    
    if (httpCode == HTTP_CODE_OK) {
      ip = http.getString();
      ip.trim(); // 去除空白字符
      Serial.println("获取成功");
    } else {
      Serial.print("HTTP错误代码: ");
      Serial.println(httpCode);
    }
    
    http.end();
  } else {
    Serial.println("HTTP连接失败");
  }
  
  return ip;
}

// 发送数据到巴法云
void sendIPToBaFa() {
  if (bfClient.connected()) {
  
    // 构建消息
    String message = externalIP;
    
    // 发送消息
    String pubCmd = "cmd=2&uid=" + String(config.apiKey) + "&topic=" + String(config.airTopic) + "&msg=" + message + "\r\n";
    //Serial.print("pubCmd= ");Serial.println(pubCmd);
    bfClient.print(pubCmd);
  }
}

    

